package com.ccn.qrcode.utils;

import com.ccn.qrcode.common.Constant;
import com.ccn.qrcode.pojo.QrcodeFilePojo;
import com.ccn.qrcode.utils.qrcodefile.ImageToTiffUtils;
import com.ccn.qrcode.utils.zxing.SelfMultiFormatWriter;
import com.ccn.qrcode.utils.zxing.decode.SelfMultiFormatReader;
import com.google.common.collect.Maps;
import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import lombok.experimental.UtilityClass;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

import static com.ccn.qrcode.common.Constant.QR_VERSION;

/**
 * <pre>
 * Created by Binary Wang on 2017-01-05.
 * @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a>
 * </pre>
 */
@UtilityClass
public class QrcodeUtils {


  /**
   * 根据自己制作的内容表来绘制二维码
   * @param filePojo 内容
   * @param fileLength 图片大小
   * @param fileType 图片类型jpg图等
   * @return raster
   */
  public static void createQrcode(QrcodeFilePojo filePojo, int fileLength, String fileType, String filePath) throws IOException {
    // 创建图片
    BufferedImage img = generateQRCodeImage(filePojo, fileLength);
    // 输出图片
    File outputfile = new File(filePath);
    ImageIO.write(img, fileType, outputfile);
    //转成最后的图
    String tifFilePath = Constant.FILE_PATH+filePojo.getFileName()+"."+Constant.FILE_OUT_PATH;
    ImageToTiffUtils.image2Tif(filePath, tifFilePath);
    // 压缩图片
//    QrcodeFileUtils.doWithPhoto(tifFilePath);
  }

  /**
   * 生成二维码图像
   * @param filePojo
   * @param fileLength  // 中间点，用来确定各个区绘制图片颜色
   * @return
   * @throws IOException
   */
  private static BufferedImage generateQRCodeImage(QrcodeFilePojo filePojo, int fileLength) throws IOException {
    // 生成二维码图像
    String filePath = filePojo.getQrcodePath();
    BitMatrix qrCodeMatrix = createQrcodeMatrix(filePath, fileLength, filePojo);
    BufferedImage bufferedImage = SelfMatrixToImageWriter.toBufferedImage(qrCodeMatrix, filePojo);
    return bufferedImage;
  }

  /**
   * 根据内容生成二维码数据
   *
   * @param content 二维码文字内容[为了信息安全性，一般都要先进行数据加密]
   * @param length  二维码图片宽度和高度
   */
  public static BitMatrix createQrcodeMatrix(String content, int length, QrcodeFilePojo qrcodeFilePojo) {
    return createQrcodeMatrix(content, length, ErrorCorrectionLevel.L, qrcodeFilePojo);
  }

  public static BitMatrix createQrcodeMatrix(String content, int length, ErrorCorrectionLevel level, QrcodeFilePojo qrcodeFilePojo) {
    Map<EncodeHintType, Object> hints = Maps.newEnumMap(EncodeHintType.class);
    // 设置字符编码
    hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8.name());
    // 指定纠错等级
    hints.put(EncodeHintType.ERROR_CORRECTION, level);
    //设置版本
    hints.put(EncodeHintType.QR_VERSION, QR_VERSION);
    try {
      return new SelfMultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, length, length, hints, qrcodeFilePojo);
    } catch (WriterException e) {
      throw new RuntimeException("内容为：【" + content + "】的二维码生成失败！", e);
    }
  }

  /**
   * 解析二维码
   *
   * @param file 二维码文件内容
   * @return 二维码的内容
   */
  public static String decodeQrcode(File file) throws IOException, NotFoundException {
    BufferedImage image = ImageIO.read(file);
    LuminanceSource source = new BufferedImageLuminanceSource(image);
    Binarizer binarizer = new HybridBinarizer(source);
    BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);

    Map<DecodeHintType, Object> hints = Maps.newEnumMap(DecodeHintType.class);
    hints.put(DecodeHintType.CHARACTER_SET, StandardCharsets.UTF_8.name());
    //优化精度
    hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
    //复杂模式，开启PURE_BARCODE模式
    hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);

    Result decode = new SelfMultiFormatReader().decode(binaryBitmap, hints);
    String text = decode.getText();
    return text;
  }






}







